package shopCart

import (
	. "awesomeProject/goods-web/api"
	protog "awesomeProject/goods-web/proto"
	"awesomeProject/order-web/forms"
	"awesomeProject/order-web/global"
	"awesomeProject/order-web/proto"
	"context"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	"strconv"
)

func List(ctx *gin.Context) {

	// 获取购物车商品
	userId, _ := ctx.Get("userId")
	zap.S().Info(userId)

	rsp, err := global.OrderSrvClient.CartItemList(context.Background(), &proto.UserInfo{
		Id: int32(userId.(uint)),
	})
	if err != nil {
		zap.S().Errorw("查询购物车列表失败")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}

	goodsIds := make([]int32, 0)
	for _, data := range rsp.Data {
		goodsIds = append(goodsIds, data.GoodsId)
	}
	if len(goodsIds) == 0 {
		ctx.JSON(http.StatusOK, gin.H{
			"total": 0,
		})
		return
	}
	// 请求商品服务，通过商品id列表获取对应的商品信息
	goodsRsp, err := global.GoodsSrvClient.BatchGetGoods(context.Background(), &protog.BatchGoodsIdInfo{
		Id: goodsIds,
	})
	if err != nil {
		zap.S().Errorw("批量获取购物车商品失败")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}

	rspMap := gin.H{ // gin.H本质上就是 map[string]interface{}
		"total": rsp.Total,
	}

	// map切片，里面存放goodMap
	goodSlice := make([]interface{}, 0)

	// 购物车商品对象
	for _, cartGood := range rsp.Data {
		// 商品信息对象
		for _, goodInfo := range goodsRsp.Data {
			if cartGood.GoodsId == goodInfo.Id { // 当这两个对象的id相同是，都是good_id字段
				goodMap := make(map[string]interface{})

				// 从订单子服务获取商品数目和是否选中，还有对应的购物车id
				goodMap["id"] = cartGood.Id
				goodMap["nums"] = cartGood.Nums
				goodMap["checked"] = cartGood.Checked
				// 从商品子服务读取商品信息
				goodMap["good_id"] = cartGood.GoodsId
				goodMap["good_name"] = goodInfo.Name
				goodMap["good_price"] = goodInfo.ShopPrice
				goodMap["good_image"] = goodInfo.GoodsFrontImage

				goodSlice = append(goodSlice, goodMap)
			}
		}
	}
	rspMap["data"] = goodSlice

	ctx.JSON(http.StatusOK, rspMap)
}
func New(ctx *gin.Context) {
	// 往购物车添加商品
	itemForm := forms.ShopCartItemForm{}
	if err := ctx.ShouldBind(&itemForm); err != nil {
		HandleValidateError(err, ctx)
		return
	}

	// 添加商品进购物车时需要查询商品是否存在
	_, err := global.GoodsSrvClient.GetGoodsDetail(context.Background(), &protog.GoodInfoRequest{
		Id: itemForm.GoodsId,
	})

	if err != nil {
		zap.S().Error("添加商品失败， 商品不存在")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}
	// 查询库存是否充足，也就是我们添加进购物车的商品数量是否合法
	invDetail, err := global.InventorySrvClient.InvDetail(context.Background(), &proto.GoodsInvInfo{
		GoodsId: itemForm.GoodsId,
	})
	if err != nil {
		zap.S().Error("查询商品库存信息失败")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}
	if invDetail.Num < itemForm.Nums {
		zap.S().Info("添加进购物车的商品数目，大于库存")
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg": "库存不足",
		})
		return
	}

	userId, _ := ctx.Get("userId")
	rsp, err := global.OrderSrvClient.CreateCartItem(context.Background(), &proto.CartItemRequest{
		UserId:  int32(userId.(uint)),
		Nums:    itemForm.Nums,
		GoodsId: itemForm.GoodsId,
	})
	if err != nil {
		zap.S().Error("添加商品到购物车失败")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"id": rsp.Id,
	})
}
func Delete(ctx *gin.Context) {
	goodIdStr := ctx.Param("id")
	goodId, err := strconv.ParseInt(goodIdStr, 10, 32)
	// 不是数字字符串
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
			"msg": "url对应的id字符串无法解析为int",
		})
		return
	}

	userId, _ := ctx.Get("userId")
	_, err = global.OrderSrvClient.DeleteCartItem(context.Background(), &proto.CartItemRequest{
		GoodsId: int32(goodId),
		UserId:  int32(userId.(uint)),
	})
	if err != nil {
		zap.S().Error("删除购物车内商品失败")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "删除成功",
	})
}
func Update(ctx *gin.Context) {

	updateForm := forms.ShopCartItemUpdateForm{}
	if err := ctx.ShouldBind(&updateForm); err != nil {
		HandleValidateError(err, ctx)
		return
	}
	goodIdStr := ctx.Param("id")
	goodId, err := strconv.ParseInt(goodIdStr, 10, 32)
	// 不是数字字符串
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
			"msg": "url对应的id字符串无法解析为int",
		})
		return
	}
	userId, _ := ctx.Get("userId")
	request := proto.CartItemRequest{
		UserId:  int32(userId.(uint)),
		GoodsId: int32(goodId),
		Nums:    updateForm.Nums,
	}
	if updateForm.Checked != nil {
		request.Checked = *updateForm.Checked
	}

	_, err = global.OrderSrvClient.UpdateCartItem(context.Background(), &request)
	if err != nil {
		zap.S().Error("更新失败")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "更新成功",
	})
}
